package com.simtop.beefsheepmaching.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.simtop.beefsheepmaching.common.ServerResponse;
import com.simtop.beefsheepmaching.dao.CountDao;
import com.simtop.beefsheepmaching.dao.OperateDao;
import com.simtop.beefsheepmaching.dao.UserDao;
import com.simtop.beefsheepmaching.pojo.*;
import com.simtop.beefsheepmaching.service.UserService;
import com.simtop.beefsheepmaching.util.AliyunMailUtil;
import com.simtop.beefsheepmaching.util.SHA256Util;
import com.simtop.beefsheepmaching.util.SmsRandomCodeUtil;
import com.simtop.beefsheepmaching.vo.UserParamsVo;
import com.simtop.beefsheepmaching.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserDao userDao;

    @Autowired
    private OperateDao operateDao;

    @Autowired
    private CountDao countDao;

    /**
     * 注册业务逻辑类
     * @param userVo
     * @return
     */
    @Override
    public ServerResponse<String> register(UserVo userVo) {
        //保证验证码不能为空
        if(userVo.getCheckCode()==null || "".equals(userVo.getCheckCode())){
            return ServerResponse.createByErrorMsg("验证码不能为空");
        }
        //前端传递的验证码和redis中的checkCode进行比对
        if(!userVo.getCheckCode().equals(redisTemplate.boundValueOps("email_"+userVo.getEmail()).get())){
            return ServerResponse.createByErrorMsg("验证码错误");
        }
        if(userVo.getLoginName()==null || userVo.getLoginName().equals("")){
            return ServerResponse.createByErrorMsg("登陆用户名不能为空");
        }
        if(userVo.getEmail()==null||userVo.getEmail().equals("")){
            return ServerResponse.createByErrorMsg("邮箱不能为空");
        }

        if(userVo.getClass()==null||userVo.getClass().equals("")){
            return ServerResponse.createByErrorMsg("班级不能为空");
        }

        //用户名、邮箱需要唯一
        int resultCount = userDao.checkLoginName(userVo.getLoginName());
        if(resultCount > 0){
            return ServerResponse.createByErrorMsg("登陆用户名已存在");
        }
        resultCount = userDao.checkEmail(userVo.getEmail());
        if(resultCount > 0){
            return ServerResponse.createByErrorMsg("邮箱已存在");
        }
        //userVo <- User
        User user = new User();
        user.setSchool(userVo.getSchool());
        user.setEmail(userVo.getEmail());
        //密码
        user.setPassword(SHA256Util.generateShaPwd(userVo.getPassword()));
        user.setCity(userVo.getCity());
        user.setProvince(userVo.getProvince());
        user.setLoginName(userVo.getLoginName());
        user.setUsername(userVo.getUsername());
        user.setRoleId(userVo.getRoleId());
        user.setClasses(userVo.getClasses());
        resultCount = userDao.insert(user);
        if(resultCount < 0){
            Operate operate = new Operate("用户注册",user.getUsername(),user.getRoleId(),"注册失败",new Date(), JSONObject.toJSONString(user));
            operateDao.insertOperate(operate);
            return ServerResponse.createByErrorMsg("用户注册失败");
        }
        Operate operate = new Operate("用户注册",user.getUsername(),user.getRoleId(),"注册成功",new Date(), JSONObject.toJSONString(user));
        operateDao.insertOperate(operate);
        return ServerResponse.createBySuccessMsg("注册成功");
    }

    /**
     * 邮箱注册验证码生成逻辑类
     * @param email
     * @return
     */
    @Override
    public ServerResponse<String> generateCheckCode(String email) {
        synchronized (this){
            //邮箱非空验证
            if(email==null||"".equals(email)){
                return ServerResponse.createByErrorMsg("邮箱不能为空,请填入有效地址");
            }
            int resultCount2 = userDao.checkEmail(email);
            if(resultCount2 > 0){
                return ServerResponse.createByErrorMsg("邮箱已存在");
            }
            //生成随机的6位数字验证码
            String verificationCode= SmsRandomCodeUtil.generateRandomSixNum();
            //调用邮箱发送
            AliyunMailUtil.sendMail(email,"牛羊肉冷链物流全流程虚拟仿真实验用户注册","您的验证码为："+verificationCode+"。此验证码三分钟内有效，请及时注册。"+"<br><br>"+"本邮件是系统自动发送的，请勿直接回复！感谢您的注册，祝您使用愉快！");
            redisTemplate.boundValueOps("email_"+email).set(verificationCode,180,TimeUnit.SECONDS);
            // todo 发送的验证码拼接了之前的验证码？？ 获取content内容时候出现getContent现象
            // todo 2019年8月28日09:23:18 接口中屏蔽验证码
            return ServerResponse.createBySuccessMsg("邮件发送成功");
        }
    }

    /**
     * 忘记密码时候，根据邮箱返回验证码
     * @param email
     * @return
     */
    @Override
    public ServerResponse<String> forgetSendEmailCode(String email) {
        //验证邮箱是否存在
        int resultCount = userDao.checkEmail(email);
        if(resultCount != 1){
            return ServerResponse.createByErrorMsg("邮箱不存在！");
        }
        //邮箱非空验证
        if(email==null||"".equals(email)){
            return ServerResponse.createByErrorMsg("邮箱不能为空,请填入有效地址");
        }
        //生成随机的验证码
        String verificationCode= SmsRandomCodeUtil.generateRandomSixNum();
        //调用邮箱发送
        AliyunMailUtil.sendMail(email,"牛羊肉冷链物流全流程虚拟仿真实验密码重置","您的验证码为："+verificationCode+"。此验证码三分钟内有效，请及时重置密码。"+"<br><br>"+"本邮件是系统自动发送的，请勿直接回复！");
        //发送成功保存邮箱地址对应的验证码 todo 3分钟 已解决
        redisTemplate.boundValueOps("forget_"+email).set(verificationCode,180,TimeUnit.SECONDS);
        return ServerResponse.createBySuccessMsg("邮件发送成功");
    }

    @Override
    public ServerResponse<String> insertBackUser(UserVo userVo) {
        System.err.println(userVo);
        // vo <- pojo
        User user = new User();
        user.setRoleId(userVo.getRoleId());
        user.setLoginName(userVo.getLoginName());
        user.setPassword(SHA256Util.generateShaPwd(userVo.getPassword()));
        user.setUsername(userVo.getUsername());
        user.setSchool(userVo.getSchool());
        user.setProvince(userVo.getProvince());
        user.setCity(userVo.getCity());
        user.setEmail(userVo.getEmail());
        user.setClasses(userVo.getClasses());
        /**
         * 查询是否存在
         */
        //用户名、邮箱需要唯一
        int resultCount1 = userDao.checkLoginName(userVo.getLoginName());
        if(resultCount1 > 0){
            return ServerResponse.createByErrorMsg("登陆用户名已存在");
        }
        int resultCount2 = userDao.checkEmail(userVo.getEmail());
        if(resultCount2 > 0){
            return ServerResponse.createByErrorMsg("邮箱已存在");
        }
        int resultCount = userDao.insertBackUser(user);
        if(resultCount != 1){
            return ServerResponse.createBySuccess("新增后台用户失败");
        }
        return ServerResponse.createBySuccessMsg("新增后台用户成功");
    }

    @Override
    public ServerResponse<String> deleteByUserId(Integer id) {
        if(id==null){
            return ServerResponse.createByErrorMsg("参数错误");
        }
        int effectNum = userDao.deleteByUserId(id);
        if(effectNum != 1){
            return ServerResponse.createByErrorMsg("删除失败");
        }
        return ServerResponse.createBySuccess("删除成功");
    }

    @Override
    public ServerResponse<String> updateBackendUser(UserVo userVo) {
        // vo <- pojo
        User user = new User();
        user.setRoleId(userVo.getRoleId());
        user.setLoginName(userVo.getLoginName());
        //密码
        User u=userDao.findById(userVo.getId());
        if(userVo.getPassword() == null){
            user.setPassword(userVo.getPassword());
        } else if (!u.getPassword().equals(userVo.getPassword())){
            user.setPassword(SHA256Util.generateShaPwd(userVo.getPassword()));
        } else{
            user.setPassword(userVo.getPassword());
        }
        user.setUsername(userVo.getUsername());
        user.setSchool(userVo.getSchool());
        user.setProvince(userVo.getProvince());
        user.setCity(userVo.getCity());
        user.setClasses(userVo.getClasses());
        //修改邮箱 todo 邮箱不能够唯一
        User user1 = userDao.checkLoginNameOrEmail(null, userVo.getEmail());
        if(userDao.checkEmail(userVo.getEmail())>0 && !user1.getId().equals(userVo.getId())){
            return ServerResponse.createByErrorMsg("该邮箱已存在！");
        }
        user.setEmail(userVo.getEmail());
        user.setAddress(userVo.getAddress());
        user.setId(userVo.getId());
        int resultCount = userDao.updateBackendUser(user);
        if(resultCount != 1){
            return ServerResponse.createByErrorMsg("修改后台用户失败");
        }
        return ServerResponse.createBySuccessMsg("修改后台用户成功");
    }

    @Override
    public List<User> findByParams(UserParamsVo params) {
        User user = new User();
        user.setUsername(params.getUsername());
        user.setSchool(params.getSchool());
        user.setClasses(params.getClasses());
        user.setLoginName(params.getLoginName());
        user.setRoleId(params.getRoleId());
        user.setId(params.getUserId());
        List<User> userList = userDao.selectByParams(user);
        return userList;
    }

    @Override
    public ServerResponse<Integer> accountUser() {
        int count = userDao.selectUserCounts();
        return ServerResponse.createBySuccess(count);
    }

    @Override
    public ServerResponse<User> findById(Integer id) {
        User user = userDao.findById(id);
        if(user == null){
            return ServerResponse.createByErrorMsg("查询用户失败");
        }
        return ServerResponse.createBySuccess(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertIlabUser(UserVo userVo) {
        User user = new User();
        user.setUsername(userVo.getUsername());
        user.setLoginName(userVo.getLoginName());
        user.setSchool(userVo.getSchool());
        user.setProvince(userVo.getProvince());
        user.setCity(userVo.getCity());
        user.setRoleId(userVo.getRoleId());
        //密码
        user.setPassword(SHA256Util.generateShaPwd(userVo.getPassword()));
        user.setEmail(userVo.getEmail());
        Operate operate = new Operate("ilab平台用户登录",user.getUsername(),user.getRoleId(),"登录成功",new Date(), JSONObject.toJSONString(user));
        operateDao.insertOperate(operate);
        return userDao.inserIlabUser(user);
    }

    @Override
    public User selectUserByUserId(Integer id) {
        return userDao.findById(id);
    }

    @Override
    public User selectUserByLoginName(String loginName) {
        return userDao.findByLoginName(loginName);
    }

    @Override
    public ServerResponse<String> updatePassword(UserVo userVo) {
        String checkCode = (String) redisTemplate.boundValueOps("forget_"+userVo.getEmail()).get();
        if(!userVo.getCheckCode().equals(checkCode)){
            return ServerResponse.createByErrorMsg("验证码错误");
        }
        if(!userVo.getNewPassword().equals(userVo.getConfirmPassword())){
            return ServerResponse.createByErrorMsg("密码不一致，请重新输入");
        }
        User user = new User();
        user.setEmail(userVo.getEmail());
        user.setPassword(SHA256Util.generateShaPwd(userVo.getNewPassword()));
        int effectNum = userDao.updatePasswordByEmail(user);
        User use = new User();
        user.setEmail(userVo.getEmail());
        List<User> u1 = userDao.selectByParams(use);
        if(effectNum == 1){
            Operate operate = new Operate("忘记密码操作",user.getUsername(),u1.get(0).getRoleId(),"修改成功",new Date(), JSONObject.toJSONString(user));
            operateDao.insertOperate(operate);
            return ServerResponse.createBySuccessMsg("更新密码成功");
        }
        Operate operate = new Operate("忘记密码操作",user.getUsername(),u1.get(0).getRoleId(),"修改失败",new Date(), JSONObject.toJSONString(user));
        operateDao.insertOperate(operate);
        return ServerResponse.createByErrorMsg("更新密码失败");
    }


    /**
     * 获取首页图表信息
     * @return
     */
    @Override
    public ServerResponse<Object> getTopPageCount() {
        /**
         * 统计各个省份人数
         */
        List<Map<String,Integer>> map = userDao.getProvinceCount();
        /**
         * 统计各个角色用户数
         */
        List<Map<String,Integer>> roles = userDao.getRoleCount();
        //总人数
        int i = userDao.selectUserCounts();
        //总访问人数
        int i1 = countDao.selectCount();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userProfile",map);
        jsonObject.put("userType",roles);
        jsonObject.put("userCount",i);
        jsonObject.put("tourist",i1);
        return ServerResponse.createBySuccess(jsonObject);
    }


    /**
     * 导入用户信息
     * @param users
     * @return
     */
    @Override
    public ServerResponse<Object> importUsers(List<Object> users){
        try{
            /**
             * 这里仅仅临时导入数据,没有进行邮箱号的判断等，不完善。
             */
            for(Object obj:users){
                User user = (User) obj;
                user.setPassword(SHA256Util.generateShaPwd(user.getPassword()));
                userDao.insertBackUser(user);
            }
            return ServerResponse.createBySuccess("导入成功");
        }catch (Exception e){
            return ServerResponse.createByErrorMsg("导入失败");
        }
    }

    @Override
    public boolean updateUserName(String loginName, String userName) {
        return this.userDao.updateUserName(loginName,userName);
    }
}
